#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QGridLayout>
#include <QPushButton>
#include <QHBoxLayout>
#include <QMessageBox>
#include <QLabel>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>
#include <QTime>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    //Init Attributes
    ui->setupUi(this);
    initialisation();

    //TODO :
    //QTABLE INIT TO REMAKE
}

//Set qTableWidget property
void MainWindow::initTable(){
    //Properties
    int nbCell=D_SIZE*M_SIZE;
    int frameSize= ui->tableWidget->width();
    int newCellSize=frameSize/nbCell;

    //Set number of cells
    ui->tableWidget->setColumnCount(nbCell);
    ui->tableWidget->setRowCount(nbCell);

    //For each cell
    for(int i=0; i<nbCell; i++){
        //Set new size
        ui->tableWidget->setRowHeight(i, newCellSize);
        ui->tableWidget->setColumnWidth(i, newCellSize);
    }
}

//Fill qTableWidget according to the domaine
void MainWindow::updateTable(Domaine domaineTmp){

    int nbLines=D_SIZE*M_SIZE; //Number of lines to be treated
    int nbCellPerLines=M_SIZE*D_SIZE; //Number of columns
    int ligne=0; // Indice de la ligne
    int colonne=0; //Indice de la colonne

    //For each line
    for(int i=0; i<nbLines; i++){
        //For each line's cell
        for(int j=0; j<nbCellPerLines; j++){
            showCell(ligne, colonne, i,j, domaineTmp); //Print cell
            colonne=colonne+1;
            //If move on next morceau
            if(colonne==M_SIZE){
                colonne=0;
            }
        }
        ligne=ligne+1;
        //On each M_SIZE lines we go to the next inferior morceau
        if(ligne==M_SIZE){
            ligne=0;
        }
    }
}

//Go to the next step of the game
void MainWindow::nextStep(){
    QTime timer;
    timer.start();
    Domaine tampon = jeuDeLaVie(this->domaine); //generate

    //Timer
    this->timeExe=timer.elapsed();

    this->domaine=tampon;
    this->updateTable(this->domaine); //print
    ui->tableWidget->repaint();

    QString timeLabel = "Time : "+QString::number(this->timeExe)+" ms.";
    ui->label_time->setText(timeLabel);
}

//Play the game on a loop
void MainWindow::run(){
    //Disable some UI interactions
    ui->btn_stop->setEnabled(true);
    ui->btn_run->setEnabled(false);
    ui->btn_next->setEnabled(false);
    ui->le_iterations->setEnabled(false);
    ui->btn_clear->setEnabled(false);

    //Print counter iterations
    this->nbIterations= ui->le_iterations->text().toInt();
    this->nbIterationsTmp=0;

    //loop : PLAY THE GAME
    int i=0;
    while(i<this->nbIterations){
        QCoreApplication::processEvents(); // allow to use buttons and ui while looping
        usleep(500);
        nextStep(); //generate next step
        i=i+1;
        //If stop button has been clicked
        if(this->nbIterationsTmp==this->nbIterations){
            break;
        }
        this->nbIterationsTmp=this->nbIterationsTmp+1;
        ui->lcd_iterations->display(this->nbIterationsTmp);
        ui->lcd_iterations->repaint();
    }
    //Prepare the next run action and stop
    this->nbIterationsTmp=0;
    ui->lcd_iterations->display(this->nbIterationsTmp);
    ui->lcd_iterations->repaint();
    stop();
}

//Print a cell in qtablewidget
void MainWindow::showCell(int line, int col, int i, int j, Domaine domaineTmp){
    QTableWidgetItem *item = new QTableWidgetItem();
    if(domaineTmp.listeMorceaux[i/M_SIZE][j/M_SIZE].listeCellules[line][col]==1){//vivante
        item->setBackgroundColor(QColor(0,0,0));
    }else{//morte
        item->setBackgroundColor(QColor(255,255,255));
    }
    item->setFlags(item->flags() & ~Qt::ItemIsEditable & ~Qt::ItemIsSelectable);
    ui->tableWidget->setItem(i,j,item);
}

//Stop loop action
void MainWindow::stop()
{
    this->nbIterationsTmp=this->nbIterations;
    ui->btn_stop->setEnabled(false);
    ui->btn_run->setEnabled(true);
    ui->le_iterations->setEnabled(true);
    ui->btn_next->setEnabled(true);
    ui->btn_clear->setEnabled(true);
}

void MainWindow::clear(){
    //Stop the loop
    stop();

    //Clear domaine (all to 0)
    clearDomaine();
    this->updateTable(this->domaine); //print
    ui->tableWidget->repaint();
}

void MainWindow::clearDomaine(){

    for(int x=0; x<D_SIZE*M_SIZE; x++){
        for(int y=0; y<D_SIZE*M_SIZE; y++){
            int line=x-(x/M_SIZE)*M_SIZE;
            int col=y-(y/M_SIZE)*M_SIZE;
            this->domaine.listeMorceaux[x/M_SIZE][y/M_SIZE].listeCellules[line][col]=0;
         }
    }
}


void MainWindow::generate(){
    clear();
    this->nbIterations=10;
    this->nbIterationsTmp=0;
    this->domain_Size=2;
    this->percentage_living=50;
    this->domaine = initialiserDomaine();
    QTime timer;
    timer.start();

    //Create first domaine
    Domaine tampon = jeuDeLaVie(this->domaine);
    this->domaine=tampon;

    //time to generate
    this->timeExe = timer.elapsed();

    //Print
    updateTable(this->domaine);
    ui->tableWidget->repaint();
}

void MainWindow::initialisation(){
    clear();
    this->nbIterations=10;
    this->nbIterationsTmp=0;
    this->domain_Size=2;
    this->percentage_living=50;
    this->domaine = initialiserDomaine();
    QTime timer;
    timer.start();

    //Create first domaine
    Domaine tampon = jeuDeLaVie(this->domaine);
    this->domaine=tampon;

    //time to generate
    this->timeExe = timer.elapsed();

    //Set qTableView
    initTable();
    updateTable(this->domaine);

    //Set UI
    ui->lcd_iterations->display(this->nbIterationsTmp); //LCD
    ui->le_iterations->setText(QString::number(this->nbIterations));//Iterations label edit
    QString timeLabel = "Time : "+QString::number(this->timeExe)+" ms.";
    ui->label_time->setText(timeLabel);

    //Buttons action connect
    QObject::connect(ui->btn_next, SIGNAL(clicked()), this, SLOT(nextStep()));
    QObject::connect(ui->btn_run, SIGNAL(clicked()), this, SLOT(run()));
    QObject::connect(ui->btn_stop, SIGNAL(clicked()), this, SLOT(stop()));
    QObject::connect(ui->btn_clear, SIGNAL(clicked()), this, SLOT(clear()));
    QObject::connect(ui->btn_generate, SIGNAL(clicked()), this, SLOT(generate()));
    QObject::connect(ui->tableWidget, SIGNAL(cellClicked(int,int)), this, SLOT(changeCellValue(int,int)));
}

void MainWindow::changeCellValue(int x, int y){
    int line=x-(x/M_SIZE)*M_SIZE;
    int col=y-(y/M_SIZE)*M_SIZE;
    if(this->domaine.listeMorceaux[x/M_SIZE][y/M_SIZE].listeCellules[line][col]==1){//vivante
        this->domaine.listeMorceaux[x/M_SIZE][y/M_SIZE].listeCellules[line][col]=0;
    }else{//morte
        this->domaine.listeMorceaux[x/M_SIZE][y/M_SIZE].listeCellules[line][col]=1;
    }
    showCell(line, col, x,y, this->domaine);
}

MainWindow::~MainWindow()
{
    delete ui;
}
